package com.zx.framework.core.util;

import java.io.File;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.log4j.Logger;

import com.zx.framework.core.env.Environment;
import com.zx.framework.core.exception.FrameworkException;

import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.cache.WebappTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;

public class FreemarkerUtil
{
	private static final Logger LOG = Logger.getLogger(FreemarkerUtil.class);
	private static Configuration cfg;
	
	private static FreemarkerUtil instance;
	
	private static MultiTemplateLoader mulLoder;
	
	public static FreemarkerUtil getInstance(Configuration newCfg,TemplateLoader ... templateLoaders) {
		if (instance == null)
		{
			synchronized (FreemarkerUtil.class)
			{
				if (instance == null)
				{
					instance = new FreemarkerUtil();
					try {
						List<TemplateLoader> loaders = new ArrayList<TemplateLoader>();
						ClassTemplateLoader classTemplateLoader = new ClassTemplateLoader(instance.getClass(),"/");
						loaders.add(classTemplateLoader);
						
						if(ObjectUtils.isNotNull(Environment.CONTEXT)){
							WebappTemplateLoader webappTemplateLoader = new WebappTemplateLoader(Environment.CONTEXT);
							loaders.add(webappTemplateLoader);
						}
						if(StringUtil.isNotEmpty(Environment.WEB_INF_REALPATH)){
							FileTemplateLoader fileTemplateLoader = new FileTemplateLoader(new File(Environment.WEB_INF_REALPATH));
							loaders.add(fileTemplateLoader);
						}
						if(templateLoaders!=null){
							loaders.addAll(Arrays.asList(templateLoaders));
						}
						
						mulLoder = new MultiTemplateLoader(loaders.toArray( new TemplateLoader[loaders.size()]));
						if(newCfg==null){
							cfg = new Configuration();
						}else{
							cfg = newCfg;
						}
						cfg.setTemplateLoader(mulLoder);
						cfg.setDateTimeFormat("yyyy-MM-dd HH:mm:ss");
						cfg.setDefaultEncoding("UTF-8");
						cfg.setLocale(Locale.getDefault());
						cfg.setObjectWrapper(new DefaultObjectWrapper());      
						cfg.setCacheStorage(new freemarker.cache.MruCacheStorage(20, 250));
					} catch (Exception e) 
					{
						LOG.error("创建模板引擎失败！", e);
						throw new FrameworkException("创建模板引擎失败！");
					} 
				}
			}
		}
		return instance;
	}
	
	public static FreemarkerUtil getInstance() 
	{
		return getInstance(null);
	}
	/**
	 * 生产模板文件
	 * @param context
	 * @param fileName
	 * @return
	 */
	public <T extends Object> String executeTemplate(Map<String,T> context,String fileName)
	{ 
		try {
			Template temp = cfg.getTemplate(fileName);  
			StringWriter writer = new StringWriter();
			temp.process(context, writer);		
			String text = writer.toString();
			return text;
		} catch (Exception e) {
			LOG.error("生成模板文件失败！", e);
			throw new FrameworkException("生成模板文件失败！");
		} 
	}
}
